<template>
  <div class="settings-container">
    <!-- 页面标题和操作按钮 -->
    <div class="page-header">
      <div class="header-background">
        <div class="bg-pattern"></div>
        <div class="bg-gradient"></div>
      </div>
      
      <div class="page-title">
        <div class="title-icon">
          <div class="icon-container" style="width: 36px; height: 36px; background: linear-gradient(135deg, #00bcd4 0%, #4dd0e1 100%); border-radius: 8px; color: white; box-shadow: 0 2px 8px rgba(0, 188, 212, 0.2);">
            <el-icon size="20"><Link /></el-icon>
            <div class="icon-glow"></div>
          </div>
        </div>
        <div class="title-content">
          <div class="title-main">
            <h1>三方配置</h1>
            <div class="title-badge">
              <el-icon><Star /></el-icon>
              <span>Config</span>
            </div>
          </div>
          <p class="page-description">
            <el-icon><Monitor /></el-icon>
            管理关联的第三方服务环境配置，确保系统正常运行
          </p>
          <div class="title-meta">
            <div class="meta-item">
              <el-icon><Setting /></el-icon>
              <span>环境管理</span>
            </div>
            <div class="meta-item">
              <el-icon><Lock /></el-icon>
              <span>安全配置</span>
            </div>
            <div class="meta-item">
              <el-icon><Menu /></el-icon>
              <span>服务监控</span>
            </div>
          </div>
        </div>
      </div>
      
      <div class="page-stats">
        <div class="stat-card running">
          <div class="stat-icon">
            <el-icon><Check /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ getConfiguredCount() }}</div>
            <div class="stat-label">已配置</div>
            <div class="stat-trend">
              <el-icon><Menu /></el-icon>
              <span>正常</span>
            </div>
          </div>
        </div>
        
        <div class="stat-card failed">
          <div class="stat-icon">
            <el-icon><Warning /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ getUnconfiguredCount() }}</div>
            <div class="stat-label">未配置</div>
            <div class="stat-trend">
              <el-icon><Warning /></el-icon>
              <span>需关注</span>
            </div>
          </div>
        </div>
        
        <div class="stat-card finished">
          <div class="stat-icon">
            <el-icon><Menu /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ getTotalServicesCount() }}</div>
            <div class="stat-label">服务数</div>
            <div class="stat-trend">
              <el-icon><Check /></el-icon>
              <span>正常</span>
            </div>
          </div>
        </div>
        
        <div class="stat-card total">
          <div class="stat-icon">
            <el-icon><Menu /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ allServiceConfigs.length }}</div>
            <div class="stat-label">总计</div>
            <div class="stat-trend">
              <el-icon><Menu /></el-icon>
              <span>全部</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 环境配置列表 -->
    <div class="config-section">
      <el-card shadow="never">
        <template #header>
          <div class="card-header">
            <div class="card-title">
              <el-icon><Link /></el-icon>
              <span>第三方服务配置</span>
            </div>
            <div class="header-actions">
              <el-button type="primary" @click="handleAddEnvironment">
                <el-icon><Plus /></el-icon>
                添加环境
              </el-button>
              <el-button 
                type="danger" 
                @click="handleBulkDelete" 
                :disabled="selectedEnvironments.length === 0"
                v-if="selectedEnvironments.length > 0"
              >
                <el-icon><Delete /></el-icon>
                批量删除 ({{ selectedEnvironments.length }})
              </el-button>
              <el-button type="warning" @click="showRecycleBin = true">
                <el-icon><DeleteFilled /></el-icon>
                回收站
              </el-button>
              <el-button type="success" @click="handleRefresh" :loading="loading">
                <el-icon><Refresh /></el-icon>
                刷新
              </el-button>
            </div>
          </div>
        </template>
        
        <div v-loading="pageLoading" class="config-list">
          <div v-if="allServiceConfigs.length === 0" class="empty-state">
            <el-empty description="暂无服务配置">
              <el-button type="primary" @click="handleAddEnvironment">
                添加第一个服务
              </el-button>
            </el-empty>
          </div>
          
          <div v-else>
            <!-- 选择控制区域 - 只有选中项目时才显示 -->
            <transition name="selection-slide">
              <div class="selection-controls" v-if="selectedEnvironments.length > 0">
                <div class="selection-info">
                  <el-checkbox 
                    :indeterminate="isIndeterminate"
                    :model-value="isAllSelected"
                    @change="handleSelectAll"
                    class="select-all-checkbox"
                  >
                    全选 ({{ selectedEnvironments.length }}/{{ allServiceConfigs.length }})
                  </el-checkbox>
                  <span class="selection-count">已选择 {{ selectedEnvironments.length }} 项</span>
                </div>
                <div class="selection-actions">
                  <el-button 
                    type="text" 
                    size="small" 
                    @click="selectedEnvironments = []"
                    class="clear-selection-btn"
                  >
                    <el-icon><Close /></el-icon>
                    取消全选
                  </el-button>
                </div>
              </div>
            </transition>
            
            <div class="environment-cards">
            <DraggableCard
              v-for="(env, index) in allServiceConfigs"
              :key="env.name"
              :index="index"
              :selected="selectedEnvironments.includes(env.name)"
              :disabled="false"
              @drag-start="handleDragStart"
              @drag-move="handleDragMove"
              @drag-end="handleDragEnd"
              @click="handleCardClick(env)"
            >
              <el-card
                class="environment-card"
                :class="{ selected: selectedEnvironments.includes(env.name) }"
                shadow="hover"
              >
              <template #header>
                <div class="env-header">
                  <div class="env-info">
                    <el-checkbox 
                      :model-value="selectedEnvironments.includes(env.name)"
                      @change="handleEnvironmentSelection(env.name, $event)"
                      @click.stop
                      class="env-checkbox"
                    />
                    <h3>{{ env.name }}</h3>
                    <el-tag :type="getEnvStatusType(env)" size="small">
                      {{ getEnvStatus(env) }}
                    </el-tag>
                  </div>
                  <div class="env-actions">
                    <el-button 
                      type="text" 
                      size="small"
                      @click.stop="handleEditEnvironment(env)"
                      :icon="Edit"
                    >
                      编辑
                    </el-button>
                    <el-button 
                      type="text" 
                      size="small"
                      @click.stop="handleDeleteEnvironment(env)"
                      :icon="Delete"
                      style="color: #f56c6c"
                    >
                      删除
                    </el-button>
                  </div>
                </div>
              </template>
              
              <div class="env-details">
                <div class="env-detail-grid">
                  <div class="detail-item">
                    <div class="detail-label">服务类型</div>
                    <el-tag :type="getServiceTypeTagType(env.service_type)" size="small" class="service-tag">
                      {{ getServiceTypeLabel(env.service_type) }}
                    </el-tag>
                  </div>
                  <div class="detail-item">
                    <div class="detail-label">连接地址</div>
                    <div class="detail-value">{{ env.host ? `${env.host}:${env.port}` : '-' }}</div>
                  </div>
                  <div class="detail-item">
                    <div class="detail-label">协议</div>
                    <div class="detail-value">{{ env.protocol || 'http' }}</div>
                  </div>
                  <div class="detail-item">
                    <div class="detail-label">用户名</div>
                    <div class="detail-value">{{ env.username || '-' }}</div>
                  </div>
                  <div class="detail-item" v-if="env.database">
                    <div class="detail-label">数据库</div>
                    <div class="detail-value">{{ env.database }}</div>
                  </div>
                  <div class="detail-item full-width" v-if="env.description">
                    <div class="detail-label">描述</div>
                    <div class="detail-value">{{ env.description }}</div>
                  </div>
                </div>
              </div>
              </el-card>
            </DraggableCard>
            </div>
            </div>
        </div>
      </el-card>
    </div>

    <!-- 环境配置表单对话框 -->
    <EnvironmentForm
      v-model="showEnvironmentForm"
      :environment="currentEnvironment"
      :existing-names="existingEnvironmentNames"
      @submit="handleEnvironmentSubmit"
    />
    
    <!-- 回收站对话框 -->
    <el-dialog
      v-model="showRecycleBin"
      width="60%"
      top="10vh"
      :append-to-body="true"
      :close-on-click-modal="false"
      class="unified-dialog recycle-bin-dialog"
    >
      <template #header>
        <DialogHeader
          icon="Delete"
          title="回收站"
          description="查看和恢复已删除的服务配置"
          type="warning"
        />
      </template>
      
      <div v-loading="recycleBinLoading" class="dialog-content recycle-bin-content">
        <div v-if="deletedConfigs.length === 0" class="empty-state">
          <el-empty description="回收站为空" />
        </div>
        <div v-else class="table-container recycle-bin-table">
          <el-table 
            :data="deletedConfigs" 
            style="width: 100%" 
            height="100%"
            :show-overflow-tooltip="true"
          >
            <el-table-column prop="service_type" label="服务类型" width="120" />
            <el-table-column prop="config_name" label="配置名称" width="200" />
            <el-table-column prop="host" label="主机" width="150" />
            <el-table-column prop="port" label="端口" width="80" />
            <el-table-column prop="deleted_time" label="删除时间" width="180" />
            <el-table-column prop="deleted_by" label="删除者" width="100" />
            <el-table-column label="操作" fixed="right" width="200">
              <template #default="scope">
                <el-button
                  type="primary"
                  size="small"
                  @click="handleRestore(scope.row)"
                >
                  恢复
                </el-button>
                <el-button
                  type="danger"
                  size="small"
                  @click="handlePermanentDelete(scope.row)"
                >
                  永久删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showRecycleBin = false">关闭</el-button>
          <el-button type="danger" @click="handleClearRecycleBin" :disabled="deletedConfigs.length === 0">
            <el-icon><Delete /></el-icon>
            清空回收站
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useSettingsStore } from '@/stores/settings'
import { useAppStore } from '@/stores/app'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Refresh, Edit, Delete, DeleteFilled, Connection, Star, Monitor, Setting, Lock, Menu, Check, Warning, Close } from '@element-plus/icons-vue'
import { componentLogger } from '@/utils/logger'
import DialogHeader from '@/components/DialogHeader.vue'
import EnvironmentForm from './components/EnvironmentForm.vue'
import DraggableCard from './components/DraggableCard.vue'

const settingsStore = useSettingsStore()
const appStore = useAppStore()
const { sidebarCollapsed } = storeToRefs(appStore)

// 响应式数据
const currentEnvironment = ref({})
const showEnvironmentForm = ref(false)
const selectedEnvironments = ref([])
const showBulkDeleteDialog = ref(false)
const showRecycleBin = ref(false)
const recycleBinLoading = ref(false)
const deletedConfigs = ref([])

// 页面级loading（用于优化并行请求）
const pageLoading = ref(false)

// 计算属性
const loading = computed(() => settingsStore.loading)
const allServiceConfigs = computed(() => settingsStore.getAllServiceConfigs())
const existingEnvironmentNames = computed(() => 
  allServiceConfigs.value.map(env => env.name)
)

// 全选相关计算属性
const isAllSelected = computed(() => {
  return allServiceConfigs.value.length > 0 && 
         selectedEnvironments.value.length === allServiceConfigs.value.length
})

const isIndeterminate = computed(() => {
  const selectedCount = selectedEnvironments.value.length
  return selectedCount > 0 && selectedCount < allServiceConfigs.value.length
})

// 统计方法
const getConfiguredCount = () => {
  return allServiceConfigs.value.filter(env => env.host && env.port).length
}

const getUnconfiguredCount = () => {
  return allServiceConfigs.value.filter(env => !env.host || !env.port).length
}

const getTotalServicesCount = () => {
  // 返回不同服务类型的数量（去重）
  const serviceTypes = [...new Set(allServiceConfigs.value.map(env => env.service_type))]
  return serviceTypes.length
}


// 方法
const handleRefresh = () => {
  fetchConfigs()
}

const fetchConfigs = async () => {
  try {
    pageLoading.value = true
    
    // ⚡ 优化：并行请求所有服务类型的配置，而不是串行
    const serviceTypes = ['flink', 'redis', 'mysql', 'starrocks', 'kafka']
    const promises = serviceTypes.map(serviceType => 
      settingsStore.fetchConfigs(serviceType).catch(error => {
        componentLogger.warn(`获取${serviceType}配置失败:`, error)
        return null // 即使单个失败也继续其他请求
      })
    )
    
    // 等待所有请求完成
    await Promise.all(promises)
  } finally {
    pageLoading.value = false
  }
}

const getEnvStatus = (env) => {
  if (!env.host || !env.port) return '未配置'
  return '已配置'
}

const getEnvStatusType = (env) => {
  if (!env.host || !env.port) return 'warning'
  return 'success'
}

// 服务类型相关方法
const getServiceTypeLabel = (serviceType) => {
  const typeMap = {
    'flink': 'Flink',
    'redis': 'Redis',
    'mysql': 'MySQL',
    'starrocks': 'StarRocks',
    'kafka': 'Kafka'
  }
  return typeMap[serviceType] || serviceType
}

const getServiceTypeTagType = (serviceType) => {
  const typeMap = {
    'flink': 'primary',
    'redis': 'danger',
    'mysql': 'success',
    'starrocks': 'warning',
    'kafka': 'info'
  }
  return typeMap[serviceType] || 'default'
}

// 选择处理
const handleEnvironmentSelection = (envName, checked) => {
  if (checked) {
    if (!selectedEnvironments.value.includes(envName)) {
      selectedEnvironments.value.push(envName)
    }
  } else {
    const index = selectedEnvironments.value.indexOf(envName)
    if (index > -1) {
      selectedEnvironments.value.splice(index, 1)
    }
  }
}

// 全选处理
const handleSelectAll = (checked) => {
  if (checked) {
    selectedEnvironments.value = allServiceConfigs.value.map(env => env.name)
  } else {
    selectedEnvironments.value = []
  }
}

// 批量删除处理
const handleBulkDelete = async () => {
  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedEnvironments.value.length} 个环境配置吗？此操作不可撤销！`,
      '确认批量删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'error'
      }
    )
    
    await deleteEnvironments(selectedEnvironments.value)
    selectedEnvironments.value = []
    ElMessage.success('批量删除成功')
  } catch (error) {
    if (error !== 'cancel') {
      componentLogger.error('批量删除失败:', error)
      ElMessage.error('批量删除失败')
    }
  }
}

// 卡片点击处理
const handleCardClick = (env) => {
  // 点击卡片进行编辑
  handleEditEnvironment(env)
}

// 添加环境
const handleAddEnvironment = () => {
  currentEnvironment.value = {}
  showEnvironmentForm.value = true
}

// 编辑环境
const handleEditEnvironment = (env) => {
  currentEnvironment.value = { ...env }
  showEnvironmentForm.value = true
}

// 删除单个环境
const handleDeleteEnvironment = async (env) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除环境 "${env.name}" 吗？此操作不可恢复！`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'error'
      }
    )
    
    await deleteEnvironments([env.name])
  } catch (error) {
    if (error !== 'cancel') {
      componentLogger.error('删除环境失败:', error)
    }
  }
}


// 删除环境的核心逻辑
const deleteEnvironments = async (envNames) => {
  try {
    let hasFlinkEnv = false
    
    if (envNames.length === 1) {
      // 单个删除
      const config = allServiceConfigs.value.find(e => e.name === envNames[0])
      if (config) {
        if (config.service_type === 'flink') {
          hasFlinkEnv = true
        }
        await settingsStore.deleteEnvironment(config.service_type, config.name)
      }
    } else {
      // 批量删除
      const configsToDelete = allServiceConfigs.value.filter(e => envNames.includes(e.name))
      hasFlinkEnv = configsToDelete.some(config => config.service_type === 'flink')
      await settingsStore.deleteEnvironments(configsToDelete)
    }
    
    // 刷新本页面的配置
    await fetchConfigs()
    
    // 如果删除了Flink环境，需要更新全局状态
    if (hasFlinkEnv) {
      await appStore.loadFlinkEnvironments()
      
      // 如果删除的环境包含当前环境，重置当前环境
      if (envNames.includes(appStore.currentFlinkEnv)) {
        const remainingEnvs = appStore.flinkEnvironments.filter(e => !envNames.includes(e.name))
        if (remainingEnvs.length > 0) {
          appStore.setCurrentFlinkEnv(remainingEnvs[0].name)
        } else {
          appStore.setCurrentFlinkEnv('')
        }
      }
    }
  } catch (error) {
    componentLogger.error('删除服务配置失败:', error)
    throw error
  }
}

// 环境表单提交处理
const handleEnvironmentSubmit = async (formData) => {
  try {
    const isEdit = !!currentEnvironment.value.name
    let serviceTypeChanged = false
    let configNameChanged = false
    
    if (isEdit) {
      // 检查服务类型或配置名称是否发生变化
      serviceTypeChanged = formData.service_type !== currentEnvironment.value.service_type
      configNameChanged = formData.name !== currentEnvironment.value.name
      
      // 编辑模式：更新现有环境
      await settingsStore.updateEnvironment(currentEnvironment.value.service_type, currentEnvironment.value.name, formData)
    } else {
      // 新增模式：创建新环境
      await settingsStore.createEnvironment(formData)
    }
    
    // 重新获取配置
    await fetchConfigs()
    
    // 如果操作的是Flink环境，需要更新全局状态
    if (formData.service_type === 'flink' || (isEdit && currentEnvironment.value.service_type === 'flink')) {
      await appStore.loadFlinkEnvironments()
    }
    
    showEnvironmentForm.value = false
    currentEnvironment.value = {}
  } catch (error) {
    componentLogger.error('保存服务配置失败:', error)
    throw error
  }
}

// 拖拽处理方法
const handleDragStart = (data) => {
  componentLogger.info('拖拽开始:', data)
}

const handleDragMove = (data) => {
  componentLogger.info('拖拽移动:', data)
}

const handleDragEnd = async (data) => {
  componentLogger.info('拖拽结束:', data)
  
  // 如果排序发生变化，保存新的排序
  if (data.startPos.x !== data.endPos.x || data.startPos.y !== data.endPos.y) {
    try {
      // 重新计算排序值
      const updatedEnvironments = allServiceConfigs.value.map((env, index) => ({
        ...env,
        sort_order: index + 1
      }))
      
      await settingsStore.saveConfigs(updatedEnvironments)
      ElMessage.success('排序已更新')
    } catch (error) {
      componentLogger.error('更新排序失败:', error)
      ElMessage.error('更新排序失败')
    }
  }
}

// 生命周期
// 回收站相关方法
const loadDeletedConfigs = async () => {
  recycleBinLoading.value = true
  try {
    const response = await fetch('/api/settings/deleted')
    const result = await response.json()
    const configs = []
    
    // 处理返回的已删除配置数据
    if (result.success && result.data && result.data.configs) {
      Object.keys(result.data.configs).forEach(serviceType => {
        Object.values(result.data.configs[serviceType]).forEach(config => {
          configs.push({
            ...config,
            service_type: serviceType,
            // 格式化删除时间
            deleted_time: config.deleted_time ? new Date(config.deleted_time).toLocaleString() : '-'
          })
        })
      })
    }
    
    deletedConfigs.value = configs
  } catch (error) {
    ElMessage.error('加载回收站数据失败')
  } finally {
    recycleBinLoading.value = false
  }
}

const handleRestore = async (config) => {
  try {
    const response = await fetch(`/api/settings/environment/${config.service_type}/${config.config_name}/restore`, {
      method: 'POST'
    })
    const result = await response.json()
    if (result.success) {
      ElMessage.success('配置恢复成功')
      loadDeletedConfigs()
      fetchConfigs()
      
      // 如果恢复的是Flink环境，需要更新全局状态
      if (config.service_type === 'flink') {
        await appStore.loadFlinkEnvironments()
      }
    } else {
      ElMessage.error(result.error || '配置恢复失败')
    }
  } catch (error) {
    ElMessage.error('恢复配置失败')
  }
}

const handlePermanentDelete = async (config) => {
  await ElMessageBox.confirm('此操作将永久删除该配置，无法恢复！', '警告', {
    type: 'warning'
  })
  
  try {
    const response = await fetch(`/api/settings/environment/${config.service_type}/${config.config_name}/permanent`, {
      method: 'DELETE'
    })
    const result = await response.json()
    if (result.success) {
      ElMessage.success('配置永久删除成功')
      loadDeletedConfigs()
    } else {
      ElMessage.error(result.error || '永久删除失败')
    }
  } catch (error) {
    ElMessage.error('永久删除失败')
  }
}

const handleClearRecycleBin = async () => {
  await ElMessageBox.confirm('此操作将清空回收站中的所有配置，无法恢复！', '警告', {
    type: 'warning'
  })
  
  try {
    for (const config of deletedConfigs.value) {
      await fetch(`/api/settings/environment/${config.service_type}/${config.config_name}/permanent`, {
        method: 'DELETE'
      })
    }
    ElMessage.success('回收站清空成功')
    loadDeletedConfigs()
  } catch (error) {
    ElMessage.error('清空回收站失败')
  }
}

// 监听回收站显示状态
watch(showRecycleBin, (show) => {
  if (show) {
    loadDeletedConfigs()
  }
})

onMounted(() => {
  fetchConfigs()
})
</script>

<style scoped>
.settings-container {
  padding: 0;
}

/* 页面头部样式 - 与Jobs页面保持一致 */
.page-header {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding: 20px 24px;
  border-radius: 12px;
  overflow: hidden;
  color: #303133;
  min-height: 120px;
  border: 1px solid #e4e7ed;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.header-background {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0.05;
  pointer-events: none;
}

.bg-pattern {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: radial-gradient(circle at 20% 20%, rgba(144, 147, 153, 0.05) 0%, transparent 50%),
                    radial-gradient(circle at 80% 80%, rgba(144, 147, 153, 0.05) 0%, transparent 50%);
  opacity: 0.6;
}

.bg-gradient {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(144, 147, 153, 0.02) 0%, rgba(177, 179, 184, 0.02) 100%);
}

.page-title {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 24px;
  flex: 1;
}

.title-content {
  flex: 1;
}

.title-icon {
  position: relative;
}

.page-header .title-icon .icon-container {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px !important;
  height: 36px !important;
  border-radius: 8px !important;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(0, 188, 212, 0.2) !important;
}

.page-header .title-icon .icon-container:hover {
  transform: scale(1.05);
  box-shadow: 0 4px 16px rgba(0, 188, 212, 0.3) !important;
}

.page-header .title-icon .icon-glow {
  position: absolute;
  top: -4px;
  left: -4px;
  right: -4px;
  bottom: -4px;
  background: linear-gradient(45deg, rgba(0, 188, 212, 0.2), rgba(77, 208, 225, 0.3));
  border-radius: 12px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.page-header .title-icon .icon-container:hover .icon-glow {
  opacity: 1;
}

.title-main {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.title-main h1 {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: #303133;
  letter-spacing: -0.3px;
}

.title-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 12px;
  background: linear-gradient(135deg, #00bcd4 0%, #4dd0e1 100%);
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  color: white;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  box-shadow: 0 2px 8px rgba(0, 188, 212, 0.25);
}

.page-description {
  margin: 0 0 12px 0;
  color: #606266;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  display: flex;
  align-items: center;
  gap: 8px;
}

.page-description .el-icon {
  font-size: 16px;
  color: #909399;
}

.title-meta {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

.meta-item {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #909399;
  font-size: 12px;
  font-weight: 500;
}

.meta-item:hover {
  color: #606266;
  transform: translateY(-1px);
}

.meta-item .el-icon {
  font-size: 16px;
}

/* 统计卡片样式 */
.page-stats {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 20px;
  flex-shrink: 0;
}

.stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
  min-width: 140px;
  position: relative;
  overflow: hidden;
}

.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(248, 250, 252, 0.6) 100%);
  opacity: 0;
  transition: all 0.3s ease;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

.stat-card:hover::before {
  opacity: 1;
}

.stat-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  font-size: 20px;
  flex-shrink: 0;
}

.stat-card.running .stat-icon {
  background: rgba(103, 194, 58, 0.1);
  color: #67c23a;
}

.stat-card.failed .stat-icon {
  background: rgba(245, 108, 108, 0.1);
  color: #f56c6c;
}

.stat-card.finished .stat-icon {
  background: rgba(64, 158, 255, 0.1);
  color: #409eff;
}

.stat-card.total .stat-icon {
  background: rgba(144, 147, 153, 0.1);
  color: #909399;
}

.stat-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.stat-number {
  font-size: 24px;
  font-weight: 700;
  color: #303133;
  line-height: 1;
  margin: 0;
}

.stat-label {
  font-size: 12px;
  color: #606266;
  font-weight: 500;
  margin: 0;
}

.stat-trend {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #909399;
  margin: 0;
}


.config-section {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 16px;
  font-weight: 600;
}

.card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #303133;
}

.card-title .el-icon {
  color: #409eff;
}

.header-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.header-actions .el-button {
  font-size: 14px;
}

.config-list {
  min-height: 200px;
  /* 移除固定高度限制，让内容自然撑开 */
}

.empty-state {
  padding: 40px 0;
}

.selection-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  margin-bottom: 20px;
  background: linear-gradient(135deg, #e8f4fd 0%, #f0f9ff 100%);
  border-radius: 12px;
  border: 1px solid #b3d8ff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}

.selection-info {
  display: flex;
  align-items: center;
  gap: 16px;
}

.select-all-checkbox {
  font-weight: 600;
  color: #303133;
}

.select-all-checkbox :deep(.el-checkbox__label) {
  font-weight: 600;
  color: #303133;
}

.selection-count {
  font-size: 12px;
  color: #409eff;
  background: rgba(64, 158, 255, 0.1);
  padding: 4px 8px;
  border-radius: 12px;
  font-weight: 500;
}

.selection-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.clear-selection-btn {
  color: #6c757d;
  padding: 4px 8px;
  border-radius: 6px;
  transition: all 0.3s ease;
}

.clear-selection-btn:hover {
  color: #f56c6c;
  background: rgba(245, 108, 108, 0.1);
}

.clear-selection-btn .el-icon {
  margin-right: 4px;
}

/* 选择控制区域的滑入动画 */
.selection-slide-enter-active {
  transition: all 0.3s ease-out;
}

.selection-slide-leave-active {
  transition: all 0.3s ease-in;
}

.selection-slide-enter-from {
  opacity: 0;
  transform: translateY(-20px);
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  margin-bottom: 0;
}

.selection-slide-leave-to {
  opacity: 0;
  transform: translateY(-20px);
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  margin-bottom: 0;
}

.selection-slide-enter-to,
.selection-slide-leave-from {
  opacity: 1;
  transform: translateY(0);
  max-height: 100px;
}

.environment-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
  gap: 24px;
  margin-top: 8px;
}

.environment-card {
  transition: all 0.3s ease;
  cursor: pointer;
  position: relative;
  border-radius: 12px;
  border: 1px solid #e4e7ed;
  background: #fff;
}

.environment-card:hover {
  transform: translateY(-4px);
  border-color: #409eff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important;
}


.env-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 8px;
  border-bottom: 1px solid #f0f2f5;
  margin-bottom: 16px;
}

.env-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.env-checkbox {
  margin-right: 4px;
}

.env-checkbox :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: #409eff;
  border-color: #409eff;
}

.env-info h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
  letter-spacing: -0.2px;
}

.env-actions {
  display: flex;
  gap: 8px;
}

.env-details {
  margin-top: 0;
}

.env-details :deep(.el-descriptions) {
  margin-bottom: 0;
}

.env-details :deep(.el-descriptions__label) {
  font-weight: 500;
  color: #606266;
  width: 80px;
}

.env-details :deep(.el-descriptions__content) {
  color: #303133;
}

/* 新的详情网格布局 */
.env-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 24px;
}

.detail-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.detail-item.full-width {
  grid-column: 1 / -1;
}

.detail-label {
  font-size: 12px;
  font-weight: 500;
  color: #909399;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.detail-value {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
  word-break: break-all;
}

.service-tag {
  font-weight: 600;
  border-radius: 6px;
  padding: 2px 8px;
}

/* 编辑模式样式 */
.edit-mode .env-actions {
  display: none;
}

.edit-mode .env-info {
  gap: 8px;
}

/* 选中状态样式 */
.selected .env-info h3 {
  color: #409eff;
}

.selected .env-details {
  color: #409eff;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .page-header {
    padding: 16px;
    flex-direction: column;
    gap: 16px;
  }
  
  .page-title {
    flex-direction: column;
    gap: 16px;
    text-align: center;
  }
  
  .title-main {
    flex-direction: column;
    gap: 8px;
  }
  
  .title-meta {
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px;
  }
  
  .page-stats {
    flex-direction: column;
    gap: 12px;
  }
  
  .stat-card {
    min-width: auto;
    justify-content: center;
  }
  
  .environment-cards {
    grid-template-columns: 1fr;
  }
  
  .env-detail-grid {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  
  .selection-controls {
    padding: 12px 16px;
    margin-bottom: 16px;
  }
  
  .selection-info {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
  
  .selection-count {
    font-size: 11px;
  }
  
  .env-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  
  .env-actions {
    align-self: flex-end;
  }
  
  .header-actions {
    flex-direction: column;
    gap: 4px;
  }
}

/* 动画效果 */
.environment-card {
  animation: fadeInUp 0.3s ease-out;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 空状态样式优化 */
.empty-state :deep(.el-empty__description) {
  margin-bottom: 16px;
}

/* 回收站对话框样式 */
.recycle-bin-dialog :deep(.el-dialog) {
  max-width: 960px;
}

.recycle-bin-dialog :deep(.el-dialog__body) {
  padding: 0;
}

.recycle-bin-content {
  padding: 20px;
  max-height: calc(70vh - 140px);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.recycle-bin-table {
  flex: 1;
  min-height: 260px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  overflow: hidden;
}

.recycle-bin-content .empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

/* 表格内容超长时显示省略号 */
.recycle-bin-dialog :deep(.el-table .cell) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 卡片阴影效果 */
.environment-card {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.environment-card:hover {
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

.environment-card.selected {
  box-shadow: 0 4px 20px rgba(64, 158, 255, 0.2);
  border-color: #409eff;
}

/* 操作按钮样式优化 */
.env-actions .el-button {
  padding: 4px 8px;
  font-size: 13px;
  border-radius: 6px;
}

.env-actions .el-button--text {
  background: rgba(64, 158, 255, 0.08);
  color: #409eff;
}

.env-actions .el-button--text:hover {
  background: rgba(64, 158, 255, 0.12);
}

.env-actions .el-button[style*="color: #f56c6c"] {
  background: rgba(245, 108, 108, 0.08);
}

.env-actions .el-button[style*="color: #f56c6c"]:hover {
  background: rgba(245, 108, 108, 0.12);
}
</style>
